using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Xml;
using System.Windows.Forms;
using System.Collections.ObjectModel;

using DevExpress.Data;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Columns;

using Microsoft.Win32;

using Verety.SharedMeta.MessagingServiceMeta.Contacts;
using Verety.SharedMeta.MessagingServiceMeta.Connection;

using Verety.SharedMeta.DirectoryServiceMeta;
using Verety.SharedMeta.DirectoryServiceMeta.Commands;
using Verety.SharedMeta.DirectoryServiceMeta.Contacts;
using Verety.SharedMeta.DirectoryServiceMeta.Enums;
using Verety.SharedMeta.DirectoryServiceMeta.Profile;
using Verety.SharedMeta.DirectoryServiceMeta.Connection;

using SBPweb.Contracts;
using SBPweb.Contracts.ChatController;
using SBPweb.Contracts.Implementation;
using SBPweb.Contracts.Messaging;
using SBPweb.Localization;
using SBPweb.Modules.Modularity;

namespace SBPweb.Modules.ContactsManager.Controls
{
    public partial class ContactListControl : SBPweb.Presentation.Windows.Forms.Controls.DockingUserControl, IRosterViewer
	{
		#region Delegates

		private delegate void CursorAndEnableHandler(Cursor newCursorStyle, bool enableControl);
		private delegate void SetCursorAndEnableDelegate(Cursor newCursorStyle, bool enable);
		private delegate void OnPaintDelegate(PaintEventArgs e);

		public delegate void MessageBoxShowEventHandler(object sender, Verety.SharedMeta.UIMeta.Common.MessageBoxEventArgs e);

		#endregion

		#region Private members

		private IDirectoryService mDirectoryService;
        private string mOtherSVStr = "Supervisor-SRG";
        private ContactGrid mContactGrid;
		private string historyPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Verety"), Application.ProductName);
        private string pMessage;

		private IChatControllerService ChatControllerModule
		{
			get
			{
				if (ParentModule == null || !ParentModule.Services.ContainsKey(typeof(IChatControllerService)))
				{
					return null;
				}
				return ParentModule.Services[typeof(IChatControllerService)] as IChatControllerService;
			}
		}

        #endregion

		#region Public properties

		public bool HideOfflineContacts
        {
            get
            {
                return mContactGrid.HideOfflineContacts;
            }
            set
            {
                this.mContactGrid.HideOfflineContacts = value;
                this.tsbToggleHideOffline.Checked = value;
            }
        }

        public override ContextMenuStrip ContextMenuStrip
        {
            get
            {
                return this.contextMenuStrip;
            }
        }

        public IDirectoryService DirectoryService
        {
            get
            {
                return mDirectoryService;
            }
			set
			{
				SetCursorAndEnable(Cursors.WaitCursor, false);

				if (mDirectoryService != null)
				{
					return;
				}
				mContactGrid.DirectoryService = mDirectoryService = value;

				mOtherSVStr = value.Configuration.GetProperty("SupervisorGroupName").ToString();
				(mDirectoryService.Contacts as IDirectoryContactsManager).OnSubscriptionPresence += new SubscriptionPresenceHandler(RosterViewer_OnSubscriptionPresence);
				(mDirectoryService.Contacts as IDirectoryContactsManager).OnSubscribedPresence += new SubscribedPresenceHandler(RosterViewer_OnSubscribedPresence);
				(mDirectoryService.Contacts as IDirectoryContactsManager).OnContactListRefreshBegin += new ContactListRefreshEndHandler(RosterViewer_OnContactListRefreshBegin);
				(mDirectoryService.Contacts as IDirectoryContactsManager).OnContactListRefreshEnd += new ContactListRefreshEndHandler(RosterViewer_OnContactListRefreshEnd);
				(mDirectoryService.Contacts as IDirectoryContactsManager).OnFirstRosterArrived += new FirstRosterArrivedHandler(RosterViewer_OnFirstRosterArrived);
				(mDirectoryService.Contacts as IDirectoryContactsManager).GetContactList();
                mDirectoryService.Connection.OnAuthenticate += new Verety.SharedMeta.MessagingServiceMeta.Connection.ConnectionHandler(Connection_OnAuthenticate);
                mDirectoryService.Connection.OnDisconnect += new Verety.SharedMeta.MessagingServiceMeta.Connection.ConnectionHandler(Connection_OnDisconnect);

				if ((mDirectoryService.Contacts as IDirectoryContactsManager).FirstRosterArrived)
				{
					SetCursorAndEnable(Cursors.Default, true);
				}

			}
		}

        void Connection_OnDisconnect(object sender)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CursorAndEnableHandler(SetCursorAndEnable), new object[] { Cursors.WaitCursor, false });
            }
            else
            {
                SetCursorAndEnable(Cursors.WaitCursor, false);
            }
        }

        void Connection_OnAuthenticate(object sender)
        {
            if ((mDirectoryService.Contacts as IDirectoryContactsManager).FirstRosterArrived)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new CursorAndEnableHandler(SetCursorAndEnable), new object[] { Cursors.Default, true });
                }
                else
                {
                    SetCursorAndEnable(Cursors.Default, true);
                }
            }
        }

		#endregion

		#region Constructor logic

		public ContactListControl(IModule parentModule)
			:base(parentModule)
		{
			InitializeComponent();

            Enabled = false;

			//DirectoryService = directoryService;

			mContactGrid = InitializeContactGrid();
			mContactGrid.Dock = DockStyle.Fill;

			this.ToolStripContainer.ContentPanel.Controls.Add(mContactGrid);

			InitializeToolStripRenderers();

			this.Dock = DockStyle.Fill;
			this.Caption = LocalizationExtender.GetString(this, "RosterViewerControlName");

			LocalizationExtender.OnInvalidatingControls += new EventHandler(LocalizationExtender_OnInvalidatingControls);

            ToolBar.ResizeStrip(SBPweb.Presentation.Windows.Forms.Controls.ToolStripSizes.Medium);
            foreach (ToolStripItem tsi in ToolBar.Items)
            {
                if (tsi.Image != null)
                {
                    tsi.Image = SBPweb.Presentation.Windows.Forms.Controls.MenuToolStrip.GetSizedImageFromImage(tsi.Image, SBPweb.Presentation.Windows.Forms.Controls.ToolStripSizes.Medium);
                }
            }

			CheckToolStripItemsVisibility();

            Resize += new EventHandler(ContactListControl_Resize);
            tstbPersonalMessage.LostFocus += new EventHandler(tstbPersonalMessage_LostFocus);

            IStateManagementService sms = ParentModule.Services.Get<IStateManagementService>();
            IStatePersistenceService persistenceService = ParentModule.Services.Get<IStatePersistenceService>();
            if (persistenceService != null)
            {
                PersistencyDictionary state = persistenceService.Load(ParentModule);
                string message = state.GetString("message", "");
                sms.Message = tstbPersonalMessage.Text = pMessage = message;
            }

		}

        void tstbPersonalMessage_LostFocus(object sender, EventArgs e)
        {
            IStateManagementService sms = ParentModule.Services.Get<IStateManagementService>();
            sms.Message = pMessage = tstbPersonalMessage.Text;
        }

        void ContactListControl_Resize(object sender, EventArgs e)
        {
            tstbPersonalMessage.Width = this.Width - 10 - tslPM.Width;
        }

		private ContactGrid InitializeContactGrid()
		{
			ContactGrid rosterGrid = new ContactGrid(ParentModule);

			rosterGrid.LookAndFeel.UseDefaultLookAndFeel = true;
			rosterGrid.AllowDrop = true;
			rosterGrid.ContextMenuStrip = this.contextMenuStrip;
			rosterGrid.EmbeddedNavigator.Name = string.Empty;
			rosterGrid.HideOfflineContacts = false;
			rosterGrid.Name = Guid.NewGuid().ToString();
			rosterGrid.SelectedRowHandle = int.MinValue;
			rosterGrid.UseAlphaBlending = true;
			rosterGrid.MainView.GroupCount = 1;
			rosterGrid.MainView.ExpandAllGroups();
			rosterGrid.MainView.SelectRow(-1);
			rosterGrid.MainView.FocusedRowHandle = -1;

			rosterGrid.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(RosterGrid_MouseDoubleClick);
			rosterGrid.SelectionChanged += new SelectionChangedEventHandler(RosterGrid_SelectionChanged);

			rosterGrid.MainView.DragObjectStart += new DevExpress.XtraGrid.Views.Base.DragObjectStartEventHandler(MainView_DragObjectStart);
			rosterGrid.MainView.DragObjectDrop += new DevExpress.XtraGrid.Views.Base.DragObjectDropEventHandler(MainView_DragObjectDrop);
			rosterGrid.MainView.MouseDown += new MouseEventHandler(MainView_MouseDown);
			rosterGrid.MainView.MouseUp += new MouseEventHandler(MainView_MouseUp);

			SetColumnCaptions(rosterGrid);

			LocalizationExtender_OnInvalidatingControls(this, new EventArgs());

			return rosterGrid;
		}

		#endregion

		#region Event handlers

		private void tstbPersonalMessage_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
		{
			if (e.KeyChar == 13)
			{
				mContactGrid.Select();
			}
		}

		private void RosterViewer_OnContactListRefreshEnd(object sender)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new CursorAndEnableHandler(SetCursorAndEnable), new object[] { Cursors.Default, true });
			}
			else
			{
				SetCursorAndEnable(Cursors.Default, true);
			}
		}

		private void RosterViewer_OnContactListRefreshBegin(object sender)
		{
			if (this.InvokeRequired)
			{
				this.BeginInvoke(new CursorAndEnableHandler(SetCursorAndEnable), new object[] { Cursors.WaitCursor, false });
			}
			else
			{
				SetCursorAndEnable(Cursors.WaitCursor, false);
			}
		}

		private void RosterViewer_OnFirstRosterArrived(object sender)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new CursorAndEnableHandler(SetCursorAndEnable), new object[] { Cursors.Default, true });
			}
			else
			{
				SetCursorAndEnable(Cursors.Default, true);
			}
		}

		private void RosterViewer_OnSubscribedPresence(object sender, IStatePresence presence)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new SubscribedPresenceHandler(RosterViewer_OnSubscribedPresence), sender, presence);
				return;
			}
			string fromBare = string.Format("{0}@{1}", presence.Sender.User, presence.Sender.Server);
			if (presence.Type == PresenceType.subscribed)
			{
				SBPweb.Controls.Windows.Common.MessageBox.Show(string.Format(LocalizationExtender.GetString("SubscriptionAllowed"), fromBare), LocalizationExtender.GetString("SubscriptionAllowedHeader"), MessageBoxButtons.OK, MessageBoxIcon.Information);
				tsbRefresh_Click(sender, EventArgs.Empty);
			}
		}

		private void RosterViewer_OnSubscriptionPresence(object sender, IStatePresence presence, SubscriptionOrientation orientation, CancelEventArgs cancel)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new SubscriptionPresenceHandler(RosterViewer_OnSubscriptionPresence), sender, presence, orientation, cancel);
				return;
			}

			cancel.Cancel = true;
			string fromBare = string.Format("{0}@{1}", presence.Sender.User, presence.Sender.Server);
			if (presence.Type == PresenceType.subscribe)
			{
				if (orientation == SubscriptionOrientation.From)
				{
					if (SBPweb.Controls.Windows.Common.MessageBox.Show(string.Format(LocalizationExtender.GetString("SubscriptionRequestArrived"), fromBare), LocalizationExtender.GetString("SubscriptionRequestArrivedHeader"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
					{
						cancel.Cancel = false;
					}
				}
				else
				{
					if (SBPweb.Controls.Windows.Common.MessageBox.Show(string.Format(LocalizationExtender.GetString("SubscriptionRequsetQuestion"), fromBare), LocalizationExtender.GetString("SubscriptionRequestQuestionHeader"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
					{
						cancel.Cancel = false;
					}
				}
			}
		}

		private void LocalizationExtender_OnInvalidatingControls(object sender, EventArgs e)
		{
			string s = LocalizationExtender.GetString("ModuleName");
			this.Caption = s;

			foreach (ToolStripItem tsi in this.ToolBar.Items)
			{
				if (tsi is ToolStripButton)
				{
					string t = LocalizationExtender.GetString(this, string.Format("{0}.Text", tsi.Name));
					if (t != null)
					{
						tsi.Text = t;
					}
				}
			}
			foreach (ToolStripItem tsmi in this.contextMenuStrip.Items)
			{
				string t = LocalizationExtender.GetString(this, string.Format("{0}.Text", tsmi.Name));
				if (t != null)
				{
					tsmi.Text = t;
				}
			}
		}

		private void MainView_MouseUp(object sender, MouseEventArgs e)
		{
			mContactGrid.ResumeRefresh();
		}

		private void MainView_MouseDown(object sender, MouseEventArgs e)
		{
			mContactGrid.SuspendRefresh();
		}

		private void MainView_DragObjectDrop(object sender, DevExpress.XtraGrid.Views.Base.DragObjectDropEventArgs e)
		{
			mContactGrid.ResumeRefresh();
		}

		private void MainView_DragObjectStart(object sender, DevExpress.XtraGrid.Views.Base.DragObjectStartEventArgs e)
		{
			mContactGrid.SuspendRefresh();
		}

		#region Toolbar handlers

		private void tsbRefresh_Click(object sender, EventArgs e)
		{
			this.RosterViewer_OnContactListRefreshBegin(this);
			(mDirectoryService.Contacts as IDirectoryContactsManager).GetContactList();
		}

		private void tsbToggleHideOffline_Click(object sender, EventArgs e)
		{
			this.mContactGrid.ToggleHideOfflineContacts();
		}

		private void tsbAddContact_Click(object sender, EventArgs e)
		{
			List<string> groups = new List<string>();
			groups.AddRange(mContactGrid.Groups);
			AddContactControl acc = new AddContactControl(this, groups);
			this.ParentModule.Host.Smartparts.Add(acc);
		}

		private void tsbDeleteContact_Click(object sender, EventArgs e)
		{
			// TODO: work with multiple rows
			DataRow[] selectedRows = this.mContactGrid.SelectedRows;

			bool flag = false;

			foreach (DataRow selectedRow in selectedRows)
			{
				if (selectedRow == null)
					continue;
				string jid = selectedRow["JID"].ToString();
				if (jid == null || jid == string.Empty)
					continue;

				bool bOk = false;

				bOk = SBPweb.Controls.Windows.Common.MessageBox.Show(string.Format(LocalizationExtender.GetString(this, "DeleteContactText"), jid), LocalizationExtender.GetString(this, "DeleteContactHeader"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes;

				if (bOk)
				{
					flag = true;

					try
					{
						string groupName = selectedRow["GroupName"].ToString();
						if (mDirectoryService.Contacts.IsSharedRosterGroup(groupName))
						{
							SBPweb.Controls.Windows.Common.MessageBox.Show(LocalizationExtender.GetString(this, "DeleteFromSRG"), LocalizationExtender.GetString(this, "DeleteFromSRGHeader"), MessageBoxButtons.OK, MessageBoxIcon.Error);
							continue;
						}
						mDirectoryService.Contacts.DeleteContact(jid, groupName);
					}
					catch (Exception ex)
					{
						ContactsManagerModule.LogManager.WriteError(this, "Deleting contact failed. (" + jid + ") " + ex.Message, "ContactManager");
					}
				}
			}

			if (flag)
			{
				mDirectoryService.Contacts.GetContactList();
			}
		}

		private void tsbRenameContact_Click(object sender, EventArgs e)
		{
			foreach (DataRow selectedRow in this.mContactGrid.SelectedRows)
			{
				if (selectedRow == null)
				{
					continue;
				}
				string jid = selectedRow["JID"].ToString();
				if (jid == null || jid == string.Empty)
				{
					continue;
				}

				try
				{
					RenameContactControl rcc = new RenameContactControl(this, jid);
					ParentModule.Host.Smartparts.Add(rcc);
				}
				catch (Exception ex)
				{
					ContactsManagerModule.LogManager.WriteError(this, "Renaming contact failed. (" + jid + ") " + ex.Message, "ContactManager");
				}
			}
		}

		private void tsbSubscribe_Click(object sender, EventArgs e)
		{
			foreach (DataRow selectedRow in this.mContactGrid.SelectedRows)
			{
				if (selectedRow == null)
					continue;
				string jid = selectedRow["JID"].ToString();
				if (jid == null || jid == string.Empty)
					continue;

				string subscription = (mDirectoryService.Contacts as IDirectoryContactsManager).GetSubscription(jid);

				if (subscription == "none" || subscription == "from")
				{
					try
					{
						(mDirectoryService.Contacts as IDirectoryContactsManager).Subscribe(jid);
					}
					catch (Exception ex)
					{
						ContactsManagerModule.LogManager.WriteError(this, "Subscribing failed. (" + jid + ") " + ex.Message, "ContactManager");
					}
				}
			}
		}

		private void tsbStartNewConference_Click(object sender, EventArgs e)
		{
			startNewConferenceMenuItem_Click(sender, e);
		}

		private void tsbStartConferenceWithGroup_Click(object sender, EventArgs e)
		{
			startGroupConferenceMenuItem_Click(sender, e);
		}

		private void tsbSendInstantMessage_Click(object sender, EventArgs e)
		{
			sendInstantMessageToolStripMenuItem_Click(sender, e);
		}

		private void tsbShowHistory_Click(object sender, EventArgs e)
		{
			foreach (DataRow dr in mContactGrid.SelectedRows)
			{
				if (dr == null || dr["JID"].ToString() == string.Empty)
				{
					continue;
				}

				string partner = dr["JID"].ToString();
				string owner = mDirectoryService.Connection.UserName + "@" + mDirectoryService.Connection.Server;
				if (partner != null && partner != string.Empty)
				{
					DirectoryInfo dirinfo = new DirectoryInfo(historyPath);
					if (!dirinfo.Exists)
					{
						return;
					}
					string fileNameStart = string.Format("{0}_{1}_", owner, partner);
					FileInfo[] fi = dirinfo.GetFiles(string.Format("{0}*.chat", fileNameStart, partner));
					if (fi.Length == 0)
					{
						fileNameStart = string.Format("{0}_{1}_", partner, owner);
						fi = dirinfo.GetFiles(string.Format("{0}*.chat", fileNameStart, partner));
					}
					if (fi.Length == 0)
					{
						return;
					}
					foreach (FileInfo f in fi)
					{
						ViewHistoryControl vchc = new ViewHistoryControl(this, dr["JID"].ToString(), f.FullName);
						ParentModule.Host.Smartparts.Add(vchc);
						//if (registryPath != string.Empty)
						//{
						//    chc.GridView.RestoreLayoutFromRegistry(registryPath);
						//}
					}
				}
			}
		}

		private void tsbRenameGroup_Click(object sender, EventArgs e)
		{
			foreach (DataRow selectedRow in this.mContactGrid.SelectedRows)
			{
				if (selectedRow == null)
				{
					continue;
				}
				if (selectedRow["JID"].ToString() != string.Empty)
				{
					continue;
				}
			    string groupName = selectedRow["GroupName"].ToString();
				RenameGroupControl rgc = new RenameGroupControl(this, groupName);
				ParentModule.Host.Smartparts.Add(rgc);
			}
		}

		private void tsbExpandAllGroups_Click(object sender, EventArgs e)
		{
			this.mContactGrid.MainView.ExpandAllGroups();
		}

		private void tsbCollapseAllGroups_Click(object sender, EventArgs e)
		{
			this.mContactGrid.MainView.CollapseAllGroups();
		}

		#endregion

		#region Context menu events

		private void contextMenuStrip_Opening(object sender, CancelEventArgs e)
		{
			if (mContactGrid.SelectedRows.Length < 1)
			{
				e.Cancel = true;
				return;
			}
			DataRow dr = this.mContactGrid.SelectedRows[0];

			if (dr == null)
			{
				//not a node
				e.Cancel = true;
				return;
			}

			if (dr["JID"].ToString() == string.Empty)
			{
				//group
				startGroupConferenceMenuItem.Visible = true;
				startNewConferenceMenuItem.Visible = false;
			}
			else
			{
				//node
				startGroupConferenceMenuItem.Visible = false;
				startNewConferenceMenuItem.Visible = true;
			}
		}

		private void sendInstantMessageToolStripMenuItem_Click(object sender, EventArgs e)
		{
			foreach (DataRow dr in this.mContactGrid.SelectedRows)
			{
				if (dr == null)
					continue;
				if (dr["JID"].ToString() == string.Empty)
				{
					//This is a group row
				}
				else
				{
					if (string.IsNullOrEmpty(dr["Resource"].ToString()) || (dr["Resource"].ToString().ToLower().Equals("unknown")))
					{
						if (SBPweb.Controls.Windows.Common.MessageBox.Show(LocalizationExtender.GetString("OfflineWarning"), LocalizationExtender.GetString("OfflineWarningCaption"), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
						{
							return;
						}
					}

					if (ChatControllerModule != null && ChatControllerModule.OpenOpenedChatWithThisContact(contactJidFromDataRow(dr), StringConstants.RouteAddresses.Chat))
					{
						continue;
					}
					try
					{
						mDirectoryService.Conversations.CreateConversation(contactJidFromDataRow(dr), StringConstants.RouteAddresses.Chat);
					}
					catch (Exception ex)
					{
						ContactsManagerModule.LogManager.WriteError(this, "Sending instant message failed. " + ex.Message, "ContactManager");
					}
				}
			}
		}

		private void startNewConferenceMenuItem_Click(object sender, EventArgs e)
		{
			ICollection<IContactId> members = null;
			DataRow[] drs = this.mContactGrid.SelectedRows;
			if (drs.Length > 0)
			{
				members = new Collection<IContactId>();
				foreach (Verety.SharedMeta.DirectoryServiceMeta.Contacts.DirectoryContactsDataset.MainViewRow dr in drs)
				{
					if (dr["JID"].ToString() != string.Empty)
					{
						members.Add(mDirectoryService.Contacts.GetContactByIdWithResource(dr.JID, dr.Resource));
					}
				}
			}
			try
			{
				mDirectoryService.Conversations.CreateConference("Conference", mDirectoryService.Conversations.GenerateConferenceId(), members, RouteAddresses.PureConference);
			}
			catch (Exception ex)
			{
				ContactsManagerModule.LogManager.WriteError(this, "Starting new conference failed. " + ex.Message, "ContactManager");
			}
		}

		private void startGroupConferenceMenuItem_Click(object sender, EventArgs e)
		{
			foreach (DataRow dr in this.mContactGrid.SelectedRows)
			{
				if (dr == null)
					continue;

				List<IContactId> contacts = mDirectoryService.Contacts.GetUsersInThisGroup(dr["GroupName"].ToString());

				try
				{
					mDirectoryService.Conversations.CreateConference("Conference", mDirectoryService.Conversations.GenerateConferenceId(), contacts, RouteAddresses.PureConference);
				}
				catch (Exception ex)
				{
					ContactsManagerModule.LogManager.WriteError(this, "Starting group conference failed. " + ex.Message, "ContactManager");
				}
			}
		}

		private void viewChatHistoryMenuItem_Click(object sender, System.EventArgs e)
		{
			tsbShowHistory_Click(sender, e);
		}

		#endregion

		#region ContactGrid events

		private delegate void RosterGrid_SelectionChangedHandler(object sender, SelectionChangedEventArgs e);
		internal void RosterGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			if (InvokeRequired)
			{
				this.BeginInvoke(new RosterGrid_SelectionChangedHandler(RosterGrid_SelectionChanged), sender, e);
				return;
			}

			CheckToolStripItemsVisibility();
		}

		private void CheckToolStripItemsVisibility()
		{
			DataRow[] rows = new DataRow[0];
			try
			{
				rows = mContactGrid.SelectedRows as DataRow[];
			}
			catch (Exception ex)
			{
				ContactsManagerModule.LogManager.WriteVerbose(this, string.Format("Error during rostergrid selectionchanged.\n{0}", ex.Message), "ContactManager");
			}

			// onlyRows
			//bool onlyRows = true;
			bool group = false;
			// onlyOneGroup
			bool onlyOneGroup;
			// onlyOneRow
			bool onlyOneRow;
			// subscribeIcon
			bool subscribeIcon;
			bool online = true;
			string jid = string.Empty;

			foreach (DirectoryContactsDataset.MainViewRow mr in rows)
			{
				jid = mr["JID"].ToString();

				if (jid == string.Empty)
				{
					group = true;
					online = false;
					subscribeIcon = false;
					break;
					//onlyRows = false;
				}

				try
				{
					online &= (mr != null && mr.Resource != StringConstants.Resources.UnknownResource);
				}
				catch (System.Data.StrongTypingException)
				{//Do nothing
					online = false;
				}

			}

			onlyOneGroup = group && (rows.Length == 1);
			onlyOneRow = !group && (rows.Length == 1);

			subscribeIcon = onlyOneRow &&
				((((mDirectoryService.Contacts as IDirectoryContactsManager).GetSubscription(jid).ToLower() == "none") ||
					((mDirectoryService.Contacts as IDirectoryContactsManager).GetSubscription(jid).ToLower() == "from"))
					&& ((mDirectoryService.Contacts as IDirectoryContactsManager).GetSubscriptionPending(jid).ToLower() != "none"));

			//IDirectoryProfileManager dpm = DirectoryService.Profile as IDirectoryProfileManager;

			// always visible buttons
			tsbRefresh.Visible = true;//&& DirectoryService.Security.Authorize("Visibility:RosterRefresh");
			tsbToggleHideOffline.Visible = true;// && DirectoryService.Security.Authorize("Visibility:RosterToggleHideOffline");
			tsbExpandAllGroups.Visible = true;// && DirectoryService.Security.Authorize("Visibility:RosterExpandAll");
			tsbCollapseAllGroups.Visible = true;// && DirectoryService.Security.Authorize("Visibility:RosterCollapseAll");
			tsbAddContact.Visible = true;// && DirectoryService.Security.Authorize("Visibility:RosterAddContact");
			tsbStartNewConference.Visible = !onlyOneGroup;// && DirectoryService.Security.Authorize("Visibility:RosterStartConference");
			startNewConferenceMenuItem.Visible = !onlyOneGroup;// && DirectoryService.Security.Authorize("Visibility:RosterStartConference");
			startVoiceConversationMenuItem.Visible = false;
			viewChatHistoryMenuItem.Visible = false;

			if (rows.Length > 0)
			{
				// onlyOneGroup
				tsbRenameGroup.Visible = onlyOneGroup && !mDirectoryService.Contacts.IsSharedRosterGroup(rows[0]["GroupName"].ToString());// && DirectoryService.Security.Authorize("Visibility:RosterRenameGroup");
				tsbStartConferenceWithGroup.Visible = onlyOneGroup;// && DirectoryService.Security.Authorize("Visibility:RosterStartGroupConference");
				startGroupConferenceMenuItem.Visible = onlyOneGroup;// && DirectoryService.Security.Authorize("Visibility:RosterStartGroupConference");
				// onlyRows
				tsbDeleteContact.Visible = !group;// && DirectoryService.Security.Authorize("Visibility:RosterDeleteContact");

				// onlyRows (subscibeIcon)
				tsbSubscribe.Visible = !group && subscribeIcon;// && DirectoryService.Security.Authorize("Visibility:RosterSubscribeIcon");
				// onlyRows (messageIcons)
				tsbSendInstantMessage.Visible = !group;// && DirectoryService.Security.Authorize("Visibility:RosterSendInstantMessage");
				sendInstantMessageToolStripMenuItem.Visible = !group;// && DirectoryService.Security.Authorize("Visibility:RosterSendInstantMessage");
				// onlyOneRow
				tsbRenameContact.Visible = onlyOneRow;// && DirectoryService.Security.Authorize("Visibility:RosterRenameContact");
				tsbShowHistory.Visible = onlyOneRow;// && DirectoryService.Security.Authorize("Visibility:ShowHistory");
				viewChatHistoryMenuItem.Visible = tsbShowHistory.Visible;
				// onlyOneRow (uncomment when implemented)
				startVoiceConversationMenuItem.Visible = false;
			}
			else /* hide everything else */
			{
				tsbRenameGroup.Visible = false;
				tsbStartConferenceWithGroup.Visible = false;
				startGroupConferenceMenuItem.Visible = false;
				tsbDeleteContact.Visible = false;
				tsbSubscribe.Visible = false;
				tsbSendInstantMessage.Visible = false;
				sendInstantMessageToolStripMenuItem.Visible = false;
				tsbRenameContact.Visible = false;
				tsbShowHistory.Visible = false;
			}
		}

		private void RosterGrid_MouseDoubleClick(object sender, MouseEventArgs e)
		{
			if (this.mContactGrid.SelectedRows.Length > 0)
			{
				DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo hi = (this.mContactGrid as ContactGrid).MainView.CalcHitInfo(new Point(e.X, e.Y));

				if (hi.InColumn || hi.InGroupColumn)
				{
					return;
				}

				// onlyRows
				bool onlyRows = true;
				foreach (DataRow dr in this.mContactGrid.SelectedRows)
					if (dr["JID"].ToString() == string.Empty) onlyRows = false;

				if (onlyRows) sendInstantMessageToolStripMenuItem_Click(sender, new EventArgs());
			}
		}

		#endregion

		#endregion

		#region Private methods

		private string contactJidFromDataRow(DataRow dr)
		{
			string contact = dr["JID"].ToString();
			if (dr["Resource"].ToString() != StringConstants.Resources.UnknownResource)
			{
				contact = string.Format("{0}/{1}", contact, dr["Resource"].ToString());
			}
			return contact;
		}

		private void SetCursorAndEnable(Cursor newCursorStyle, bool enable)
		{
            if (InvokeRequired)
            {
                this.Invoke(new SetCursorAndEnableDelegate(SetCursorAndEnable), newCursorStyle, enable);
                return;
            }
			this.Cursor = newCursorStyle;
			this.ToolBar.Enabled = enable;
			this.Enabled = enable;
		}

		private void InitializeToolStripRenderers()
		{
			this.ToolStripRenderer = new SBPweb.Controls.Windows.Bar.ToolStripRenderer();
			this.contextMenuStrip.Renderer = this.ToolStripRenderer;
			this.ToolStripContainer.TopToolStripPanel.Renderer = this.ToolStripRenderer;
			this.ToolStripContainer.LeftToolStripPanel.Renderer = this.ToolStripRenderer;
			this.ToolStripContainer.RightToolStripPanel.Renderer = this.ToolStripRenderer;
			this.ToolStripContainer.BottomToolStripPanel.Renderer = this.ToolStripRenderer;
			this.ToolStripContainer.ContentPanel.Renderer = this.ToolStripRenderer;
			this.ToolBar.Renderer = this.ToolStripRenderer;
		}

		private void SetColumnCaptions(ContactGrid grid)
		{
			foreach (GridColumn gc in grid.MainView.Columns)
			{
				if (gc.FieldName.Equals("colIcon"))
				{
					gc.Caption = string.Empty;
				}
				else if (gc.FieldName.Equals("GroupName"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnGroupName");
				}
				else if (gc.FieldName.Equals("NickName"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnNickName");
				}
				else if (gc.FieldName.Equals("JID"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnJID");
				}
				else if (gc.FieldName.Equals("Resource"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnResource");
				}
				else if (gc.FieldName.Equals("Availability"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnAvailability");
				}
				else if (gc.FieldName.Equals("Status"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnStatus");
				}
				else if (gc.FieldName.Equals("Message"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnMessage");
				}
				else if (gc.FieldName.Equals("GroupOrderNo"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnGroupOrderNo");
				}
				else if (gc.FieldName.Equals("StatusHistory"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnStatusHistory");
				}
				else if (gc.FieldName.Equals("IP"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnIP");
				}
				else if (gc.FieldName.Equals("Workstation"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnWorkstation");
				}
				else if (gc.FieldName.Equals("OperatingMode"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnOperatingMode");
				}
				else if (gc.FieldName.Equals("Reason"))
				{
					gc.Caption = LocalizationExtender.GetString(this, "ColumnReason");
				}
				else
				{
					gc.Caption = string.Empty;
				}
			}
		}

		#endregion

		#region Internal methods

		internal void UnSubScribeFromEvents()
		{
			this.startNewConferenceMenuItem.Click -= new EventHandler(startNewConferenceMenuItem_Click);
			this.startGroupConferenceMenuItem.Click -= new EventHandler(startGroupConferenceMenuItem_Click);

			if (mContactGrid != null)
			{
				mContactGrid.MouseDoubleClick -= new System.Windows.Forms.MouseEventHandler(RosterGrid_MouseDoubleClick);
				mContactGrid.SelectionChanged -= new SelectionChangedEventHandler(RosterGrid_SelectionChanged);
				if (mContactGrid.MainView != null)
				{
					mContactGrid.MainView.DragObjectStart -= new DevExpress.XtraGrid.Views.Base.DragObjectStartEventHandler(MainView_DragObjectStart);
					mContactGrid.MainView.DragObjectDrop -= new DevExpress.XtraGrid.Views.Base.DragObjectDropEventHandler(MainView_DragObjectDrop);
					mContactGrid.MainView.MouseDown -= new MouseEventHandler(MainView_MouseDown);
					mContactGrid.MainView.MouseUp -= new MouseEventHandler(MainView_MouseUp);
				}
				mContactGrid.UnSubScribeFromEvents();
			}

			(mDirectoryService.Contacts as IDirectoryContactsManager).OnSubscriptionPresence -= new SubscriptionPresenceHandler(RosterViewer_OnSubscriptionPresence);
			(mDirectoryService.Contacts as IDirectoryContactsManager).OnSubscribedPresence -= new SubscribedPresenceHandler(RosterViewer_OnSubscribedPresence);
			(mDirectoryService.Contacts as IDirectoryContactsManager).OnContactListRefreshBegin -= new ContactListRefreshEndHandler(RosterViewer_OnContactListRefreshBegin);
			(mDirectoryService.Contacts as IDirectoryContactsManager).OnContactListRefreshEnd -= new ContactListRefreshEndHandler(RosterViewer_OnContactListRefreshEnd);
			(mDirectoryService.Contacts as IDirectoryContactsManager).OnFirstRosterArrived -= new FirstRosterArrivedHandler(RosterViewer_OnFirstRosterArrived);

			LocalizationExtender.OnInvalidatingControls -= new EventHandler(LocalizationExtender_OnInvalidatingControls);
		}

		#endregion

		#region Overridden methods

		protected override void OnPaint(PaintEventArgs e)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new OnPaintDelegate(OnPaint), e);
			}
			else
			{
				base.OnPaint(e);
			}
		}

		#endregion

		#region Public methods

		public void Finalize()
		{
			UnSubScribeFromEvents();

            IStatePersistenceService persistenceService = ParentModule.Services.Get<IStatePersistenceService>();
            if (persistenceService != null)
            {
                PersistencyDictionary state = persistenceService.Load(ParentModule);
                state.SetString("message", pMessage);
                persistenceService.Save(ParentModule, state);
            }
		}

		#endregion

        #region IRegistryPersistenceSupport Members
/*
        public override void Save(Microsoft.Win32.RegistryKey PersistenceKey)
        {
			try
			{
				base.SaveDockProperties(PersistenceKey); 
				UIPersister.SaveDockingSmartPart(PersistenceKey, this);

				PersistenceKey.SetValue("ViewCount", TabControl.TabPages.Count, RegistryValueKind.DWord);
				PersistenceKey.SetValue("AskPhoneNumber", this.mAskPhoneNumber ? (UInt32)1 : (UInt32)0, RegistryValueKind.DWord);
				PersistenceKey.SetValue("PhoneNumber", this.mPhoneNumber, RegistryValueKind.String);
				PersistenceKey.SetValue("SelectedViewIndex", this.TabControl.SelectedTabPageIndex, RegistryValueKind.DWord);

				foreach (object o in TabControl.TabPages)
				{
					ViewTabPage vtp = o as ViewTabPage;
					string keyName = String.Format("View:{0}", TabControl.TabPages.IndexOf(vtp));
					RegistryKey regKey = PersistenceKey.CreateSubKey(keyName);

					regKey.SetValue("ViewName", vtp.Text, RegistryValueKind.String);
					(vtp.ContactGrid as ContactGrid).MainView.SaveLayoutToRegistry(regKey.Name);
					(vtp.ContactGrid as ContactGrid).SaveOptionsToRegistry(regKey);
				}

				if (this.TabControl.TabPages.Count > 0 && this.TabControl.TabPages[0] != null)
				{
					string name = string.Format("{0}\\{1}", PersistenceKey.Name.Substring(0, PersistenceKey.Name.LastIndexOf("\\")), "Layout");
					((this.TabControl.TabPages[0] as ViewTabPage).ContactGrid as ContactGrid).MainView.SaveLayoutToRegistry(name, DevExpress.Utils.OptionsLayoutGrid.FullLayout);
				}


//				this.Bar.Manager.SaveLayoutToRegistry(PersistenceKey.Name);

			}
			catch (Exception ex)
			{
				ContactsManagerModule.LogManager.WriteError("Persistence data saving failed. " + ex.Message);
			}
        }

        public override void Load(Microsoft.Win32.RegistryKey PersistenceKey)
        {
			try
			{
				base.LoadDockProperties(PersistenceKey); 
				UIPersister.LoadDockingSmartPart(PersistenceKey, this);

				mPersistenceKey = PersistenceKey;

				mAskPhoneNumber = ((int)PersistenceKey.GetValue("AskPhoneNumber")) == 1 ? true : false;
				mPhoneNumber = (string)PersistenceKey.GetValue("PhoneNumber");
				int tabCount = (int)PersistenceKey.GetValue("ViewCount");
				TabControl.SelectedTabPageIndex = (int)PersistenceKey.GetValue("SelectedViewIndex");

				for (int i = 0; i < tabCount; i++)
				{
					RegistryKey regKey = PersistenceKey.OpenSubKey(String.Format("View:{0}", i));
					SetRosterGrid();
					ViewTabPage vtp = TabControl.SelectedTabPage as ViewTabPage;
					(vtp.ContactGrid as ContactGrid).RestoreOptionsFromRegistry(regKey);
					vtp.Text = regKey.GetValue("ViewName").ToString();
					//vtp.ContactGrid.MainView.RestoreLayoutFromRegistry(regKey.Name);
					tsbToggleHideOffline.Checked = this.SelectedTabPage.ContactGrid.HideOfflineContacts;
				}
				if (this.TabControl.TabPages.Count > 0 && this.TabControl.TabPages[0] != null)
				{
					string name = string.Format("{0}\\{1}", PersistenceKey.Name.Substring(0, PersistenceKey.Name.LastIndexOf("\\")), "Layout");
					((this.TabControl.TabPages[0] as ViewTabPage).ContactGrid as ContactGrid).MainView.RestoreLayoutFromRegistry(name, DevExpress.Utils.OptionsLayoutGrid.FullLayout);
					SetColumnCaptions((this.TabControl.TabPages[0] as ViewTabPage).ContactGrid as ContactGrid);
				}

//				this.Bar.Manager.RestoreLayoutFromRegistry(PersistenceKey.Name);
			}
			catch (Exception ex)
			{
				ContactsManagerModule.LogManager.WriteError("Persistence data loading failed. " + ex.Message);
			}
        }
*/
        #endregion

		#region Persistency

		public void LoadPersistency(PersistencyDictionary state)
		{
			if (mContactGrid != null)
			{
				mContactGrid.LoadPersistency(state);
			}
		}

		public void SavePersistency(PersistencyDictionary state)
		{
			if (mContactGrid != null)
			{
				mContactGrid.SavePersistency(state);
			}
		}

		#endregion

        #region IRosterViewer Members

        public DataRow SelectedRow
        {
            get 
			{
				return mContactGrid.GetRowFromHandle(mContactGrid.SelectedRowHandle);
			}
        }

        #endregion

        #region IService Members

        public SBPweb.Modules.Modularity.IModule Module
        {
            get 
			{
				return Module; 
			}
        }

        #endregion
    }
}
